﻿/***********************************************************************************************
 * 
 * ProjectName: WMSSoft.Lib.WinKStart
 * 
 * Description: Class to read Usersettings from Disk
 * 
 * Created:     05.07.2014
 * 
 * Author:      matthias wagler - matthias@WMSSoft.de
 * 
 * Copyright:   Copyright 2014 by WMSSoft.net
 * 
 * License:     GPLv3
 * 
 * History:     05.07.2014 - matthias wagler matthias@WMSSoft.de   -   Created
 * 
 **********************************************************************************************/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using WMSSoft.Lib.Basic;
using WMSSoft.Lib.Basic.Xml;
using WMSSoft.Lib.Enums;
using WMSSoft.Lib.Const;
using WMSSoft.Lib.WinKStart.Model.UserSettings;

namespace WMSSoft.Lib.WinKStart
{
    public static class cUserSettingsReader
    {
        static bool _bSettingsLoaded = false;
        static string _PathApplication = "";
        static string _LoadedFilenamePath = "";
        static string _sGUIStyle = "";

        static cStyleReader _StylesReader = null;
        static Model.WinKStartSettings m_WinKStartSettings = null;
        static RegionSettings _TabpageSettings = null;
        static MenuItemSettings _MenuItemSettings = null;
        static SystemControlSettings _SystemControlSettings = null;
        static SearchSettings _SearchSettings = null;
        static Dictionary<string, string> _SearchableDataSources = new Dictionary<string, string>();
        static Dictionary<string, string> _InstalledSearchEngines = new Dictionary<string, string>();

        static System.Xml.XmlDocument _UserConfigDoc = null;

        #region Properties

        public static Dictionary<string, string> SearchableDataSources
        {
            get { return _SearchableDataSources; }
        }

        public static Dictionary<string, string> InstalledSearchEngines
        {
            get { return _InstalledSearchEngines; }
        }

        /// <summary>
        /// Return true if Config was loaded from disk
        /// </summary>
        public static bool ConfigLoaded
        {
            get { return _bSettingsLoaded; }
        }

        //public static string Style
        //{
        //    get { return _sGUIStyle; }
        //    set { _sGUIStyle = value; }
        //}

        public static cStyleReader StyleReader
        {
            get { return _StylesReader; }
        }

        public static Model.WinKStartSettings WinKStart
        {
            get { return m_WinKStartSettings; }
        }

        /// <summary>
        /// Get or set the settings for Tabpages
        /// </summary>
        public static RegionSettings RegionSettings
        {
            get { return _TabpageSettings; }
            set { _TabpageSettings = value; }
        }

        /// <summary>
        /// Get or set settings for StartmenuItems
        /// </summary>
        public static MenuItemSettings MenuItemSettings
        {
            get { return _MenuItemSettings; }
            set { _MenuItemSettings = value; }
        }

        /// <summary>
        /// Get or set settings for SystemcontrolItems
        /// </summary>
        public static SystemControlSettings SystemControlSettings
        {
            get { return _SystemControlSettings; }
            set { _SystemControlSettings = value; }
        }

        public static string ApplicationPath
        {
            get { return _PathApplication; }
        }

        public static string ImagesPath
        {
            get { return System.IO.Path.Combine(_PathApplication, "Images"); }
        }

        public static string LanguagesPath
        {
            get { return System.IO.Path.Combine(_PathApplication, "languageFiles"); }
        }

        public static string ConfigPath
        {
            get { return System.IO.Path.Combine(_PathApplication, "config"); }
        }

        public static string DataSourcesPath
        {
            get { return System.IO.Path.Combine(_PathApplication, "DataSources"); }
        }

        public static string StylesPath
        {
            get { return System.IO.Path.Combine(_PathApplication, "Styles"); }
        }

        public static string FunctionsPaths
        {
            get { return System.IO.Path.Combine(_PathApplication, "Functions"); }
        }

        public static string SearchEnginesPath
        {
            get { return System.IO.Path.Combine(_PathApplication, "WebSearchEngines"); }
        }

        #endregion

        #region public Methods
        public static Model.WinKStartSettings LoadSettingsObject(string Filename)
        {
            try
            {
                Model.WinKStartSettings tmpSettingsObject = new Model.WinKStartSettings();
                if (System.IO.File.Exists(Filename) == true)
                {

                    tmpSettingsObject = Deserialize(tmpSettingsObject, Filename);
                }
                else return null;

                return tmpSettingsObject;
            }
            catch (Exception Ex)
            {
                throw new Exception(LanguageStrings.GetText("Error while loading configuration!"), Ex);
            }
        }

        public static void LoadSettings(string Filename)
        {
            try
            {
                _LoadedFilenamePath = Filename;
                //first extract the application path
                _PathApplication = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);

                m_WinKStartSettings = new Model.WinKStartSettings();

                //Load Styles
                _StylesReader = new cStyleReader();
                _StylesReader.Load();

                _bSettingsLoaded = false;
                if (_UserConfigDoc != null) _UserConfigDoc = null;
                _UserConfigDoc = new System.Xml.XmlDocument();
                if (System.IO.File.Exists(Filename) == true)
                {

                    m_WinKStartSettings = Deserialize(m_WinKStartSettings, Filename);

                    if (m_WinKStartSettings != null)
                    {
                        //set the used style
                        _StylesReader.SetActiveStyle(m_WinKStartSettings.Behavior.DefaultStyle);
                    }

                    if (_TabpageSettings != null) _TabpageSettings = null;
                    if (_MenuItemSettings != null) _MenuItemSettings = null;
                    if (_SearchSettings != null) _SearchSettings = null;

                    //load program configuration from XML file
                    //an existing instance will be killed to create a new kindly object                   
                    
                    //now load the config - File as XMLDocument                    
                    _UserConfigDoc.Load(Filename);

                    System.Xml.XmlNode myRootNode = cXmlHelpers.GetRootNode(_UserConfigDoc);

                    ProcessLoad_General(cXmlHelpers.GetElementNode(myRootNode, XMLNodeNames.USERSETTINGS_XMLNODE__SECTION_GENERAL));
                    //ProcessLoad_SearchableDataSources(cXmlHelpers.GetElementNode(myRootNode, XMLNodeNames.USERSETTINGS_XMLNODE__SEARCH));
                    //ProcessLoad_InstalledSearchEngines(cXmlHelpers.GetElementNode(myRootNode, XMLNodeNames.USERSETTINGS_XMLNODE__SEARCH));

                    _bSettingsLoaded = true;
                }
                else
                {
                    _TabpageSettings = new RegionSettings();
                    _MenuItemSettings = new MenuItemSettings();
                    _SystemControlSettings = new SystemControlSettings();
                    //_StylesReader.SetActiveStyle("");
                    _bSettingsLoaded = true;
                    //CreateEmptyConfig();
                }
                    //throw new Exception(LanguageStrings.GetText("Configuration not found!"));
            }
            catch (Exception Ex)
            {
                throw new Exception(LanguageStrings.GetText("Error while loading configuration!"), Ex);
            }
        }

        public static void SaveSettings(string Filename, Model.WinKStartSettings Settings)
        {
            try
            {
                if (Filename.Length > 0)
                {
                    Serialize(Settings, Filename);
                }
                else throw new Exception(LanguageStrings.GetText("Configuration can't be Save!"));
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Could not save Settings!", Ex, EMessageTypes.Error);
            }
        }

        public static void SaveSettings(string Filename)
        {
            try
            {
                if (Filename.Length > 0)
                {
                    if (_bSettingsLoaded == true)
                    {

                        Serialize(m_WinKStartSettings, Filename);
                    }
                    else
                    {

                    }
                }
                else throw new Exception(LanguageStrings.GetText("Configuration can't be Save!"));
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Could not save Settings!", Ex, EMessageTypes.Error);
            }
        }

        public static void SaveSettings()
        {
            SaveSettings(_LoadedFilenamePath);
        }

        public static bool AddSearchingDataSource(string DataSource)
        {
            try
            {
                if (_SearchableDataSources.ContainsKey(DataSource) == false)
                {
                    _SearchableDataSources.Add(DataSource, "");
                    return true;
                } return false;
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't add SearchableDataSource!", Ex);
            }
        }

        public static bool IsSearchingDataSource(string DataSource)
        {
            try
            {
                return _SearchableDataSources.ContainsKey(DataSource);                
            }
            catch (Exception Ex)
            {
                return false;
            }
        }

        public static bool AddInstalledSearchEngine(string SearchEngine)
        {
            try
            {
                if (_InstalledSearchEngines.ContainsKey(SearchEngine) == false)
                {
                    _InstalledSearchEngines.Add(SearchEngine, "");
                    return true;
                } return false;
            }
            catch (Exception Ex)
            {
                throw new Exception("Can't add InstalledSearchEngine!", Ex);
            }
        }

        public static bool IsInstalledSearchEngine(string SearchEngine)
        {
            try
            {
                return _InstalledSearchEngines.ContainsKey(SearchEngine);
            }
            catch (Exception Ex)
            {
                return false;
            }
        }

        #endregion

        #region Private Methods

        #region Load Settings

        private static void ProcessLoad_General(System.Xml.XmlNode Node)
        {
            try
            {
                if (Node != null)
                {
                    //Load option Region SelectEvent
                    System.Xml.XmlNode tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_REGION_SELECT);

                    if (tmpNode != null)
                    {
                        eSelectEvent tmpSelectEvent = (eSelectEvent)Enum.Parse(typeof(eSelectEvent), tmpNode.InnerText);
                        _TabpageSettings = new RegionSettings(tmpSelectEvent);

                    }
                    else
                        _TabpageSettings = new RegionSettings();

                    tmpNode = null;
                    //Load option ShowAllUsers on Programs
                    tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_PROGRAMS_SHOWALLUSERS);

                    if (tmpNode != null)
                    {
                        bool tmpShowAllUserItems = bool.Parse(tmpNode.InnerText);
                        _MenuItemSettings = new MenuItemSettings(tmpShowAllUserItems);
                    }
                    else
                        _MenuItemSettings = new MenuItemSettings();

                    tmpNode = null;
                    //Load option Show Administrative Tools
                    tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_SYSTEMCONTROL_ADM_TOOLS);

                    if (tmpNode != null)
                    {
                        bool tmpShowAdministrativeTools = bool.Parse(tmpNode.InnerText);
                        _SystemControlSettings = new SystemControlSettings(tmpShowAdministrativeTools);
                    }
                    else
                        _SystemControlSettings = new SystemControlSettings();

                    tmpNode = null;
                    //load option GUI Style
                    tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_GUI_STYLE);

                    if (tmpNode != null)
                    {
                        _sGUIStyle = tmpNode.InnerText;
                    }
                    else
                        _sGUIStyle = "Default";

                    //set the used style
                    _StylesReader.SetActiveStyle(_sGUIStyle);
                }
            }
            catch (Exception Ex)
            {
                throw new Exception(LanguageStrings.GetText("Can't load Tabpage Settings!"), Ex);
            }
        }

        private static void ProcessLoad_SearchableDataSources(System.Xml.XmlNode Node)
        {
            try
            {
                System.Xml.XmlNode tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__SEARCHABLE_DATASOURCES);

                foreach (System.Xml.XmlNode SubNode in tmpNode.ChildNodes)
                {
                    if (SubNode.Name == XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__DATASOURCE)
                    {
                        if (_SearchableDataSources.ContainsKey(SubNode.InnerText) == false)
                            _SearchableDataSources.Add(SubNode.InnerText, "");
                    }
                }
            }
            catch (Exception Ex)
            {
                throw new Exception(LanguageStrings.GetText("Can't load Search Settings!"), Ex);
            }
        }

        private static void ProcessLoad_InstalledSearchEngines(System.Xml.XmlNode Node)
        {
            try
            {
                System.Xml.XmlNode tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__INSTALLED_SEARCH_ENGINES);

                foreach (System.Xml.XmlNode SubNode in tmpNode.ChildNodes)
                {
                    if (SubNode.Name == XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__SEARCH_ENGINE)
                    {
                        if (_InstalledSearchEngines.ContainsKey(SubNode.InnerText) == false)
                            _InstalledSearchEngines.Add(SubNode.InnerText, "");
                    }
                }
            }
            catch (Exception Ex)
            {
                throw new Exception(LanguageStrings.GetText("Can't load Search Settings!"), Ex);
            }
        }

        #endregion

        #region Save Settings

        private static void ProcessSave_General(System.Xml.XmlNode Node)
        {
            try
            {
                if (Node != null)
                {
                    System.Xml.XmlNode tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_REGION_SELECT);

                    if (tmpNode == null)
                    {
                        tmpNode = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_REGION_SELECT);
                        Node.AppendChild(tmpNode);
                    }

                    if (tmpNode != null)
                    {
                        cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_REGION_SELECT).InnerText = RegionSettings.SelectEvent.ToString();
                    }

                    tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_PROGRAMS_SHOWALLUSERS);

                    if (tmpNode == null)
                    {
                        tmpNode = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_PROGRAMS_SHOWALLUSERS);
                        Node.AppendChild(tmpNode);
                    }

                    if (tmpNode != null)
                    {
                        cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_PROGRAMS_SHOWALLUSERS).InnerText = _MenuItemSettings.ShowAllUsers.ToString();
                    }

                    tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_SYSTEMCONTROL_ADM_TOOLS);

                    if (tmpNode == null)
                    {
                        tmpNode = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_SYSTEMCONTROL_ADM_TOOLS);
                        Node.AppendChild(tmpNode);
                    }

                    if (tmpNode != null)
                    {
                        cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_SYSTEMCONTROL_ADM_TOOLS).InnerText = _SystemControlSettings.ShowAdministraiveTools.ToString();
                    }

                    tmpNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_GUI_STYLE);
                    if (tmpNode == null)
                    {
                        tmpNode = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_GUI_STYLE);
                        Node.AppendChild(tmpNode);
                    }

                    if (tmpNode != null)
                    {
                        cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE__GENERAL_OPTION_GUI_STYLE).InnerText = _sGUIStyle;
                    }
                }
            }
            catch (Exception Ex)
            {
                throw new Exception(LanguageStrings.GetText("Can't save Tabpage Settings!"), Ex);
            }
        }

        static void ProcessSave_SearchableDataSources(System.Xml.XmlNode Node)
        {
            try
            {

                if (Node == null)
                {
                    //Create node Search
                    //XMLNodeNames.USERCONFIG_XMLNODE__SEARCH
                    System.Xml.XmlNode tmpRootNode = cXmlHelpers.GetRootNode(_UserConfigDoc);
                    System.Xml.XmlNode subNode = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE__SEARCH);
                    tmpRootNode.AppendChild(subNode);

                    Node = subNode;
                }

                if (Node != null)
                {
                    //if the subnode Searchable_DataSources doesn't exist create it
                    System.Xml.XmlNode SearchableDataSourcesNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__SEARCHABLE_DATASOURCES);
                    if (SearchableDataSourcesNode == null)
                    {
                        SearchableDataSourcesNode = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__SEARCHABLE_DATASOURCES);
                        Node.AppendChild(SearchableDataSourcesNode);
                    }

                    if (SearchableDataSourcesNode != null)
                    {
                        //Clear all subnodes
                        SearchableDataSourcesNode.RemoveAll();
                        System.Xml.XmlNode SearchableDataSource = null;

                        Dictionary<string, string>.KeyCollection tmpKeys = _SearchableDataSources.Keys;
                        foreach (string Key in tmpKeys)
                        {

                            SearchableDataSource = null;
                            SearchableDataSource = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__DATASOURCE);
                            if (SearchableDataSource != null)
                            {
                                SearchableDataSource.InnerText = Key;
                                SearchableDataSourcesNode.AppendChild(SearchableDataSource);
                            }
                        }
                    }
                }
            }
            catch (Exception Ex)
            {

            }
        }

        static void ProcessSave_InstalledSearchEngines(System.Xml.XmlNode Node)
        {
            try
            {

                if (Node == null)
                {
                    //Create node Search
                    //XMLNodeNames.USERCONFIG_XMLNODE__SEARCH
                    System.Xml.XmlNode tmpRootNode = cXmlHelpers.GetRootNode(_UserConfigDoc);
                    System.Xml.XmlNode subNode = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE__SEARCH);
                    tmpRootNode.AppendChild(subNode);

                    Node = subNode;
                }

                if (Node != null)
                {
                    //if the subnode Searchable_DataSources doesn't exist create it
                    System.Xml.XmlNode InstalledSearchEngineNode = cXmlHelpers.GetElementNode(Node, XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__INSTALLED_SEARCH_ENGINES);
                    if (InstalledSearchEngineNode == null)
                    {
                        InstalledSearchEngineNode = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__INSTALLED_SEARCH_ENGINES);
                        Node.AppendChild(InstalledSearchEngineNode);
                    }

                    if (InstalledSearchEngineNode != null)
                    {
                        //Clear all subnodes
                        InstalledSearchEngineNode.RemoveAll();
                        System.Xml.XmlNode InstalledSearchEngine = null;

                        Dictionary<string, string>.KeyCollection tmpKeys = _InstalledSearchEngines.Keys;
                        foreach (string Key in tmpKeys)
                        {

                            InstalledSearchEngine = null;
                            InstalledSearchEngine = _UserConfigDoc.CreateElement(XMLNodeNames.USERSETTINGS_XMLNODE_SUBNODE__SEARCH_ENGINE);
                            if (InstalledSearchEngine != null)
                            {
                                InstalledSearchEngine.InnerText = Key;
                                InstalledSearchEngineNode.AppendChild(InstalledSearchEngine);
                            }
                        }
                    }
                }
            }
            catch (Exception Ex)
            {

            }
        }

        #endregion

        static bool Serialize<T>(T value, string Filename)
        {
            if (value == null)
            {
                return false;
            }
            try
            {
                if (File.Exists(Filename) == true)
                    File.Delete(Filename);

                XmlSerializer xmlserializer = new XmlSerializer(typeof(T));
                TextWriter oTextwriter = new StreamWriter(Filename);
                xmlserializer.Serialize(oTextwriter, value);
                oTextwriter.Close();
                return true;
            }
            catch (Exception Ex)
            {
                CMessagelogging.AppendMessage("Error while saving usersettings!", Ex, EMessageTypes.Error);
                return false;
            }
        }

        static Model.WinKStartSettings Deserialize<T>(T value, string Filename)
        {
            XmlSerializer xmlserializer = new XmlSerializer(typeof(T));
            TextReader oTextreadere = new StreamReader(Filename);
            Model.WinKStartSettings oData = (Model.WinKStartSettings)xmlserializer.Deserialize(oTextreadere);
            return oData;
        }
        #endregion

    }
}
